package com.knowledge.review.designPatterns.behavioralpattern.visitorpattern;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

// 访问者接口
public interface IVisitor {
    void visit(Engineer engineer);

    void visit(Pm pm);
}

// 具体的访问者类,访问者角色(CEO)
class CeoVisitor implements IVisitor {
    @Override
    public void visit(Engineer engineer) {
        System.out.println(engineer.getName() + "KPI为:" + engineer.getKpi());
    }

    @Override
    public void visit(Pm pm) {
        System.out.println(pm.getName() + "KPI为:" + pm.getKpi());
    }
}

// 具体的访问者类,访问者角色(CTO)
class CtoVisitor implements IVisitor {
    @Override
    public void visit(Engineer engineer) {
        System.out.println(engineer.getName() + "工作内容:" + engineer.getCodeLine() + "行代码");
    }

    @Override
    public void visit(Pm pm) {
        System.out.println(pm.getName() + "工作内容:" + pm.getProject() + "个项目");
    }
}

@Data
// 抽象元素(员工)
abstract class Employee {
    private String name;
    private Integer kpi;

    public Employee(String name) {
        this.name = name;
        this.kpi = new Random().nextInt(10);
    }

    public abstract void accept(IVisitor visitor);
}

// 具体元素(程序员)
class Engineer extends Employee {
    public Engineer(String name) {
        super(name);
    }

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public Integer getCodeLine() {
        return new Random().nextInt(10000);
    }
}

// 具体元素(项目经理)
class Pm extends Employee {
    public Pm(String name) {
        super(name);
    }

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public Integer getProject() {
        return new Random().nextInt(10);
    }
}

@AllArgsConstructor
class Report {
    private List<Employee> employeeList;

    public void showReport(IVisitor visitor) {
        for (Employee employee : employeeList) {
            employee.accept(visitor);
        }
    }
}

class Test {
    // 测试
    public static void main(String[] args) {
        List<Employee> employeeList = new ArrayList<>();
        employeeList.add(new Engineer("工程师A"));
        employeeList.add(new Engineer("工程师B"));
        employeeList.add(new Pm("项目经理A"));
        employeeList.add(new Engineer("工程师C"));
        employeeList.add(new Engineer("工程师D"));
        employeeList.add(new Pm("项目经理B"));
        Report report = new Report(employeeList);
        System.out.println("=============CEO==============");
        report.showReport(new CeoVisitor());
        System.out.println("=============CTO==============");
        report.showReport(new CtoVisitor());
        // =============CEO==============
        // 工程师AKPI为:2
        // 工程师BKPI为:4
        // 项目经理AKPI为:4
        // 工程师CKPI为:2
        // 工程师DKPI为:0
        // 项目经理BKPI为:0
        // =============CTO==============
        // 工程师A工作内容:5811行代码
        // 工程师B工作内容:9930行代码
        // 项目经理A工作内容:7个项目
        // 工程师C工作内容:4591行代码
        // 工程师D工作内容:333行代码
        // 项目经理B工作内容:4个项目
    }
}